package com.harmony.pilot.data.service.impl;

import com.harmony.pilot.common.constants.ServiceConstants;
import com.harmony.pilot.common.dto.CodeContext;
import com.harmony.pilot.common.dto.CompletionItem;
import com.harmony.pilot.data.service.CodeQLService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * CodeQL服务实现
 */
@Slf4j
@Service
public class CodeQLServiceImpl implements CodeQLService {
    
    @Value("${codeql.database-path}")
    private String databasePath;
    
    @Value("${codeql.cli-path}")
    private String cliPath;
    
    @Value("${codeql.query-timeout}")
    private int queryTimeout;
    
    @Override
    public List<CompletionItem> querySymbols(CodeContext context) {
        log.info("Querying symbols from CodeQL database");
        
        List<CompletionItem> items = new ArrayList<>();
        
        try {
            // 检查数据库是否存在
            if (!isDatabaseAvailable()) {
                log.warn("CodeQL database not available, returning empty results");
                return items;
            }
            
            // 构建CodeQL查询
            String query = buildSymbolQuery(context);
            
            // 执行查询
            String result = executeCodeQLQuery(query);
            
            // 解析结果
            items = parseSymbolResults(result);
            
            log.info("Found {} symbols from CodeQL", items.size());
            
        } catch (Exception e) {
            log.error("Failed to query symbols from CodeQL", e);
        }
        
        return items;
    }
    
    @Override
    public Map<String, Object> analyzeCode(CodeContext context) {
        log.info("Analyzing code with CodeQL");
        
        Map<String, Object> result = new HashMap<>();
        
        try {
            if (!isDatabaseAvailable()) {
                log.warn("CodeQL database not available");
                result.put("status", "unavailable");
                return result;
            }
            
            // 执行多个分析查询
            List<Map<String, Object>> issues = new ArrayList<>();
            
            // 1. 安全问题检查
            issues.addAll(checkSecurityIssues(context));
            
            // 2. 代码质量检查
            issues.addAll(checkQualityIssues(context));
            
            // 3. 性能问题检查
            issues.addAll(checkPerformanceIssues(context));
            
            result.put("issues", issues);
            result.put("total", issues.size());
            result.put("status", "success");
            
        } catch (Exception e) {
            log.error("Failed to analyze code with CodeQL", e);
            result.put("status", "error");
            result.put("error", e.getMessage());
        }
        
        return result;
    }
    
    /**
     * 检查数据库是否可用
     */
    private boolean isDatabaseAvailable() {
        File dbDir = new File(databasePath);
        return dbDir.exists() && dbDir.isDirectory();
    }
    
    /**
     * 构建符号查询
     */
    private String buildSymbolQuery(CodeContext context) {
        // 这是一个简化的示例查询
        // 实际应该根据CodeQL的查询语言编写
        StringBuilder query = new StringBuilder();
        query.append("import cpp\n\n");
        query.append("from Function f\n");
        query.append("where f.getFile().getRelativePath().matches(\"%").append(context.getFilePath()).append("%\")\n");
        query.append("select f.getName(), f.getType(), f.getLocation()");
        return query.toString();
    }
    
    /**
     * 执行CodeQL查询
     */
    private String executeCodeQLQuery(String query) {
        try {
            // 创建临时查询文件
            File queryFile = File.createTempFile("codeql-query-", ".ql");
            queryFile.deleteOnExit();
            java.nio.file.Files.writeString(queryFile.toPath(), query);
            
            // 构建命令
            ProcessBuilder pb = new ProcessBuilder(
                cliPath,
                "query", "run",
                "--database=" + databasePath,
                queryFile.getAbsolutePath()
            );
            
            Process process = pb.start();
            
            // 读取输出
            StringBuilder output = new StringBuilder();
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(process.getInputStream()))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    output.append(line).append("\n");
                }
            }
            
            // 等待执行完成
            process.waitFor();
            
            return output.toString();
            
        } catch (Exception e) {
            log.error("Failed to execute CodeQL query", e);
            return "";
        }
    }
    
    /**
     * 解析符号查询结果
     */
    private List<CompletionItem> parseSymbolResults(String result) {
        List<CompletionItem> items = new ArrayList<>();
        
        // 简化的解析逻辑
        // 实际应该根据CodeQL的输出格式解析
        String[] lines = result.split("\n");
        for (String line : lines) {
            if (line.trim().isEmpty() || line.startsWith("#")) {
                continue;
            }
            
            // 假设格式为: name | type | location
            String[] parts = line.split("\\|");
            if (parts.length >= 2) {
                items.add(CompletionItem.builder()
                        .label(parts[0].trim())
                        .kind(ServiceConstants.KIND_FUNCTION)
                        .detail(parts[1].trim())
                        .source("codeql")
                        .confidence(0.85)
                        .build());
            }
        }
        
        return items;
    }
    
    /**
     * 检查安全问题
     */
    private List<Map<String, Object>> checkSecurityIssues(CodeContext context) {
        List<Map<String, Object>> issues = new ArrayList<>();
        
        // 示例：检查不安全的函数调用
        String code = context.getCode();
        if (code != null && code.contains("strcpy")) {
            Map<String, Object> issue = new HashMap<>();
            issue.put("type", "security");
            issue.put("severity", "error");
            issue.put("message", "Use of unsafe function 'strcpy'");
            issue.put("rule", "cpp/unsafe-string-function");
            issue.put("source", "codeql");
            issues.add(issue);
        }
        
        return issues;
    }
    
    /**
     * 检查代码质量问题
     */
    private List<Map<String, Object>> checkQualityIssues(CodeContext context) {
        List<Map<String, Object>> issues = new ArrayList<>();
        
        // 示例：检查代码复杂度
        String code = context.getCode();
        if (code != null) {
            int complexity = calculateComplexity(code);
            if (complexity > 10) {
                Map<String, Object> issue = new HashMap<>();
                issue.put("type", "quality");
                issue.put("severity", "warning");
                issue.put("message", "High cyclomatic complexity: " + complexity);
                issue.put("rule", "cpp/high-complexity");
                issue.put("source", "codeql");
                issues.add(issue);
            }
        }
        
        return issues;
    }
    
    /**
     * 检查性能问题
     */
    private List<Map<String, Object>> checkPerformanceIssues(CodeContext context) {
        List<Map<String, Object>> issues = new ArrayList<>();
        
        // 示例：检查低效的循环
        String code = context.getCode();
        if (code != null && code.matches(".*for.*\\.size\\(\\).*")) {
            Map<String, Object> issue = new HashMap<>();
            issue.put("type", "performance");
            issue.put("severity", "info");
            issue.put("message", "Repeated call to size() in loop");
            issue.put("rule", "cpp/inefficient-loop");
            issue.put("source", "codeql");
            issues.add(issue);
        }
        
        return issues;
    }
    
    /**
     * 计算代码复杂度（简化版）
     */
    private int calculateComplexity(String code) {
        int complexity = 1;
        
        // 统计控制流语句
        complexity += countOccurrences(code, "if ");
        complexity += countOccurrences(code, "else ");
        complexity += countOccurrences(code, "for ");
        complexity += countOccurrences(code, "while ");
        complexity += countOccurrences(code, "case ");
        complexity += countOccurrences(code, "&&");
        complexity += countOccurrences(code, "||");
        
        return complexity;
    }
    
    /**
     * 统计字符串出现次数
     */
    private int countOccurrences(String text, String pattern) {
        int count = 0;
        int index = 0;
        while ((index = text.indexOf(pattern, index)) != -1) {
            count++;
            index += pattern.length();
        }
        return count;
    }
}

